using System;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using System.ComponentModel;
using System.IO.Packaging;
using System.Workflow.ComponentModel.Design;
using System.ComponentModel.Design;
using System.IO;

namespace OWA.Activities
{
    [Designer(typeof(PackageScopeDesigner), typeof(IDesigner))]
	public abstract class PackageScope
        : SequenceActivity
	{
        Package _package;

        [Category("OWA")]
        [Description("The package used inside the PackageScope.")]
        public Package Package
        {
            get { return _package; }
            set { _package = value; }
        }

        protected override void OnActivityChangeAdd(ActivityExecutionContext executionContext, 
            Activity addedActivity)
        {
            if (addedActivity is AbstractPackageActivity == false)
            {
                throw new Exception("Only AbstractPackageActivity children allowed");
            }
            base.OnActivityChangeAdd(executionContext, addedActivity);
        }

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            MemoryStream packageStream = new MemoryStream();
            byte[] packageBytes = LoadPackage();
            packageStream.Write(packageBytes, 0, packageBytes.Length);
            _package = Package.Open(packageStream, FileMode.Open, FileAccess.ReadWrite);
            this.UserData.Add("stream", packageStream);
            return base.Execute(executionContext);
        }

        protected override void OnSequenceComplete(ActivityExecutionContext executionContext)
        {
            MemoryStream ms = (MemoryStream)UserData["stream"];
            _package.Flush();
            SavePackage(ms.ToArray());
            _package.Close();
            ms.Close();
            UserData["stream"] = null; 
            base.OnSequenceComplete(executionContext);
        }

        protected abstract byte[] LoadPackage();

        protected abstract void SavePackage(byte[] packageContent);
    }
}
